package parsers;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Scanner;
import javax.swing.text.html.HTMLEditorKit;
import javax.swing.text.html.parser.ParserDelegator;
import error.GedivaException;

public abstract class AbstractParser implements IParser
{
    public AbstractParser(String delim)
    {
        DELIMETER = delim;
    }

    /**
     * Inner class for processing all data when reading a base URL.
     * 
     * @author Duvall (adapted)
     */
    private class ParserListener extends HTMLEditorKit.ParserCallback
    {
        public void handleText(char[] data, int pos)
        {
            myText.append(data);
        }
    }

    private StringBuilder myText = new StringBuilder();

    private static final String FILE_NOT_FOUND = "Could not find ";

    private String DELIMETER = "\\s*,\\s*";

    public List<List<String>> parseFile(File file, String delim)
    {
        DELIMETER = delim;
        Scanner scan;
        ArrayList<List<String>> result = new ArrayList<List<String>>();
        try
        {
            scan = new Scanner(file);
        }
        catch (FileNotFoundException e)
        {
            throw new GedivaException(FILE_NOT_FOUND + file.getName());
        }

        while (scan.hasNextLine())
        {
            String line = scan.nextLine();
            result.add(Arrays.asList(line.split(DELIMETER)));
        }

        return result;
    }

    public List<String> parseFirstLine(File file)
    {
        Scanner scan;
        try
        {
            scan = new Scanner(file);
        }
        catch (FileNotFoundException e)
        {
            throw new GedivaException(FILE_NOT_FOUND + file.getName());
        }
        String line = scan.nextLine();
        return Arrays.asList(line.split(DELIMETER));
    }

    @Override
    public List<String> parseFirstLine(URL path)
    {
        myText.delete(0, myText.length());
        try
        {
            new ParserDelegator().parse(
                    new InputStreamReader(path.openStream()),
                    new ParserListener(), true);
        }
        catch (IOException e)
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        String input = myText.toString();
        input = input.replaceAll(DELIMETER, ",");
        input = input.replaceAll("\\s", "\n");
        Scanner scan = new Scanner(input);
        List<String> result = new ArrayList<String>();
        String line = scan.nextLine();
        result.addAll(Arrays.asList((line.split(","))));
        return result;
    }

    @Override
    public List<List<String>> parseURL(URL path)
    {
        myText.delete(0, myText.length());
        try
        {
            new ParserDelegator().parse(
                    new InputStreamReader(path.openStream()),
                    new ParserListener(), true);
        }
        catch (IOException e)
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        String input = myText.toString();
        input = input.replaceAll(DELIMETER, ",");
        input = input.replaceAll("\\s", "\n");
        Scanner scan = new Scanner(input);
        ArrayList<List<String>> result = new ArrayList<List<String>>();
        while (scan.hasNextLine())
        {
            String line = scan.nextLine();
            result.add(Arrays.asList(line.split(",")));
        }
        return result;
    }

}
